﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using Common.Core;
using Microsoft.Practices.ObjectBuilder2;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;

namespace Common.Unity.Configuration
{
	class InjectionPropertyValueElement : InjectionPropertyElement
	{
		public override void DeserializeElement(System.Xml.XmlReader reader)
		{
			Properties.Add( new ConfigurationProperty( "elementType", typeof(string), GetType().AssemblyQualifiedName ) );
			Properties.Remove( "propertyType" );
			Properties.Add( new ConfigurationProperty( "propertyType", typeof(string), null, ConfigurationPropertyOptions.None ) );
			base.DeserializeElement(reader);
		}

		public override InjectionMember CreateInjectionMember()
		{
			PropertyTypeName = ResolvePropertyTypeName();

			// HACK: I wouldn't look at this if I were you. :)
			var field = typeof(InjectionPropertyElement).GetField( "valueElement", BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.Instance );
			var instance = field.GetValue( this ) as InstanceValueElement;
			if ( instance != null )
			{
				instance.TypeName = !string.IsNullOrEmpty( instance.TypeName ) ? instance.TypeName : PropertyTypeName;
			}

			return base.CreateInjectionMember();
		}

		string ResolvePropertyTypeName()
		{
			var key = ThreadLocalStorage.Peek<NamedTypeBuildKey>();
			var info = key.Type.GetProperty( Name );
			var result = info != null ? info.PropertyType.AssemblyQualifiedName : null;
			return result;
		}

		public override bool IsReadOnly()
		{
			return false;
		}
	}
}